package com.ruoyi.common.utils;

import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.time.DateTimeException;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;

/**
 * 微信支付请求验证器（适用于HttpServletRequest）
 */
public class WechatPay2ValidatorForRequest {

    private static final Logger log = LoggerFactory.getLogger(WechatPay2ValidatorForRequest.class);

    protected static final int RESPONSE_EXPIRED_MINUTES = 5;

    private final Verifier verifier;
    private final String requestId;
    private final String body;

    public WechatPay2ValidatorForRequest(Verifier verifier, String requestId, String body) {
        this.verifier = verifier;
        this.requestId = requestId;
        this.body = body;
    }

    public boolean validate(HttpServletRequest request) throws IOException {
        // 1. 检查请求时间
        if (!checkRequestTimestamp(request)) {
            log.warn("请求时间校验失败");
            return false;
        }

        // 2. 获取签名信息
        String signature = getHeader(request, "Wechatpay-Signature");
        String serialNo = getHeader(request, "Wechatpay-Serial");
        String nonce = getHeader(request, "Wechatpay-Nonce");
        String timestamp = getHeader(request, "Wechatpay-Timestamp");

        if (signature == null || serialNo == null || nonce == null || timestamp == null) {
            log.warn("缺少必要的微信支付头信息");
            return false;
        }

        // 3. 构造验签名串
        String message = buildMessage(timestamp, nonce, body);

    // 4. 验证签名
    try {
        return verifier.verify(serialNo, message.getBytes(StandardCharsets.UTF_8), signature);
    } catch (Exception e) {
        log.error("签名验证失败", e);
        return false;
    }
    }

    private boolean checkRequestTimestamp(HttpServletRequest request) {
        String timestampStr = getHeader(request, "Wechatpay-Timestamp");
        if (timestampStr == null) {
            return false;
        }

        try {
            Instant responseTime = Instant.ofEpochSecond(Long.parseLong(timestampStr));
            Instant now = Instant.now();
            return Duration.between(responseTime, now).abs().toMinutes() <= RESPONSE_EXPIRED_MINUTES;
        } catch (DateTimeException | NumberFormatException e) {
            log.warn("无效的时间戳格式: {}", timestampStr);
            return false;
        }
    }

    private String buildMessage(String timestamp, String nonce, String body) {
        return timestamp + "\n"
                + nonce + "\n"
                + body + "\n";
    }

    private String getHeader(HttpServletRequest request, String headerName) {
        return request.getHeader(headerName);
    }
}